/**
 * Copyright (c) 2020 wuchenxi
 * walter-blog is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 * http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 * <p>
 * <p>
 * Mulan Permissive Software License，Version 2
 * <p>
 * Mulan Permissive Software License，Version 2 (Mulan PSL v2)
 * January 2020 http://license.coscl.org.cn/MulanPSL2
 */
package com.walter.blog.business.user.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.walter.auth.SecurityUtil;
import com.walter.blog.aop.aop.LoginAop;
import com.walter.blog.business.email.Mail;
import com.walter.blog.business.email.service.MailService;
import com.walter.blog.business.user.service.UserService;
import com.walter.constant.SessionConstant;
import com.walter.db.pojo.User;
import com.walter.response.ResponseKit;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.util.Date;
import java.util.Objects;

/**
 * 用户
 *
 * @author wuchenxi
 * @date 2020-08-07 17:15:01
 */
@Validated
@Api(value = "/user", tags = "用户操作接口")
@RestController
@RequestMapping("/user")
@PreAuthorize("permitAll()")
public class UserController {

    @Autowired(required = false)
    private PasswordEncoder passwordEncoder;

    @Resource
    private UserService userService;

    @Resource
    private HttpSession httpSession;

    @Resource
    private MailService mailService;

    @Resource
    private LoginAop loginAop;

    @ApiOperation(value = "用户注册")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "注册成功"),
            @ApiResponse(code = 400, message = "当前帐号已存在！")})
    @PostMapping("/add_user")
    public ResponseKit<Object> addUser(@Valid User user, String validCode) {

        if (StringUtils.isEmpty(validCode)) {
            return ResponseKit.error(400, "请输入验证码！");
        }

        Object attribute = httpSession.getAttribute(SessionConstant.REGISTER_VALID_CODE);
        if (!Objects.equals(String.valueOf(attribute), validCode)) {
            return ResponseKit.error(400, "验证码输入错误！请重新输入！");
        }

        int count = userService.countByMail(user.getMail());
        if (count > 0) {
            return ResponseKit.error(400, "当前邮箱已被注册，请重新填写新邮箱！");
        }

        String password = passwordEncoder.encode(user.getPassword());

        user.setPassword(password);
        user.setAccount(StringUtils.trim(user.getAccount()));
        user.setNickname(StringUtils.trim(user.getNickname()));
        user.setCreateTime(new Date());
        User one = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getAccount, user.getAccount()));
        if (one != null) {
            return ResponseKit.error(400, "当前帐号已存在！");
        }
        userService.save(user);

        httpSession.removeAttribute(SessionConstant.REGISTER_VALID_CODE);
        return ResponseKit.success();
    }

    @ApiOperation(value = "判断用户是否已经登录")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "用户已经登录"),
            @ApiResponse(code = 403, message = "用户还没有登录！")
    })
    @GetMapping("/is_login")
    public ResponseKit<Object> isLogin() {
        if (SecurityUtil.authenticated()) {
            return ResponseKit.error(HttpStatus.FORBIDDEN.value(), "用户还未登录！");
        }
        return ResponseKit.success();
    }

    @ApiOperation(value = "用户注册发送验证码")
    @PostMapping("/sendValidCode")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "发送成功"),
            @ApiResponse(code = 500, message = "服务器异常"),
            @ApiResponse(code = 400, message = "参数错误！")
    })
    public ResponseKit<Object> sendValidCode(String mail) {
        mail = StringUtils.trim(mail);

        if (StringUtils.isEmpty(mail)) {
            return ResponseKit.error(400, "请输入邮箱！");
        }

        int count = userService.countByMail(mail);
        if (count > 0) {
            return ResponseKit.error(400, "当前邮箱已被注册，请重新填写新邮箱！");
        }

        long round = Math.round((Math.random() + 1) * 1000);
        httpSession.setAttribute(SessionConstant.REGISTER_VALID_CODE, round);
        String html = "<html>" +
                "<head></head>" +
                "<body>" +
                "<h1>请使用以下验证码注册记忆旅途账号<h1>" +
                "<br>" +
                "<h3>" + round + "</h3>" +
                "</body>" +
                "</html>";

        boolean success = mailService.sendHtmlMail(Mail.builder()
                .content(html)
                .subject("记忆旅途账号注册")
                .to(new String[]{mail})
                .build());

        return success ? ResponseKit.success() : ResponseKit.error(500, "邮件发送失败！请重试！");
    }

    @ApiOperation(value = "用户重置密码发送验证码")
    @PostMapping("/sendResetPasswordValidCode")
    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "发送成功"),
            @ApiResponse(code = 500, message = "服务器异常"),
            @ApiResponse(code = 400, message = "参数错误！")
    })
    public ResponseKit<Object> sendResetPasswordValidCode(String mail) {
        mail = StringUtils.trim(mail);

        if (StringUtils.isEmpty(mail)) {
            return ResponseKit.error(400, "请输入邮箱！");
        }

        long round = Math.round((Math.random() + 1) * 1000);
        httpSession.setAttribute(SessionConstant.REGISTER_VALID_CODE, round);
        String html = "<html>" +
                "<head></head>" +
                "<body>" +
                "<h1>请使用以下验证码重置记忆旅途密码<h1>" +
                "<br>" +
                "<h3>" + round + "</h3>" +
                "</body>" +
                "</html>";

        boolean success = mailService.sendHtmlMail(Mail.builder()
                .content(html)
                .subject("记忆旅途账号重置密码")
                .to(new String[]{mail})
                .build());

        return success ? ResponseKit.success() : ResponseKit.error(500, "邮件发送失败！请重试！");
    }

    @ApiOperation(value = "重置密码")
    @ApiResponses(value = {@ApiResponse(code = 200, message = "修改成功")})
    @PostMapping("/reset_password")
    public ResponseKit<Object> restPassword(@Valid User user, String validCode) {

        if (StringUtils.isEmpty(validCode)) {
            return ResponseKit.error(400, "请输入验证码！");
        }

        Object attribute = httpSession.getAttribute(SessionConstant.REGISTER_VALID_CODE);
        if (!Objects.equals(String.valueOf(attribute), validCode)) {
            return ResponseKit.error(400, "验证码输入错误！请重新输入！");
        }

        User one = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getMail, user.getMail()));
        if (one != null) {
            String password = passwordEncoder.encode(user.getPassword());
            one.setPassword(password);
            userService.updateById(one);
            httpSession.removeAttribute(SessionConstant.REGISTER_VALID_CODE);
            return ResponseKit.success();
        }
        return ResponseKit.error(400, "当前邮箱还未注册！");
    }

}
